﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using FindProject.Common;
using FindProject.Model;

namespace FindProject
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
            // 移除初始加载目录树，根节点将仅在执行查询时创建
            this.containerBody.SplitterDistance = this.containerBody.Width / 2;
            this.treeView1.ImageList = this.imageList1;
            this.treeView2.ImageList = this.imageList1;
            this.button2.Enabled = false; // 默认禁用拷贝路径按钮
            UpdateButtonsState();
        }

        /// <summary>
        /// 搜索目录
        /// </summary>
        private static List<string> SearchFolders = AppConfig.Options.SearchFolders;

        /// <summary>
        /// 根节点
        /// </summary>
        private static TreeNode Root = null!;

        /// <summary>
        /// SVN根节点
        /// </summary>
        private static TreeNode SvnRoot = null!;

        /// <summary>
        /// 目录
        /// </summary>
        private static Dictionary<string, TreeNode> DirecotryTreeNode = new Dictionary<string, TreeNode>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// SVN项目字典
        /// </summary>
        private static Dictionary<string, SvnProjectInfo> SvnProjectDictionary = new Dictionary<string, SvnProjectInfo>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// SVN仓库节点缓存
        /// </summary>
        private static Dictionary<string, TreeNode> SvnRepositoryTreeNodes = new Dictionary<string, TreeNode>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// 选择项目路径
        /// </summary>
        private string SelectedPath = string.Empty;

        /// <summary>
        /// 选择VS路径
        /// </summary>
        private string SelectedVsPath = string.Empty;

        /// <summary>
        /// 选择的SVN项目
        /// </summary>
        private SvnProjectInfo? SelectedSvnProject = null;

        /// <summary>
        /// 选中的SVN仓库URL（仓库分组节点）
        /// </summary>
        private string SelectedRepositoryUrl = string.Empty;

        #region 事件
        private void Main_Shown(object sender, EventArgs e)
        {
            this.textBox1.Focus();
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                btnSearch_Click(sender, e);
            }
        }
        #endregion

        #region TreeView 操作
        private const string TREE_ROOT_NAME = "本地项目";
        private const string TREE_SVN_ROOT_NAME = "SVN 项目";

        /// <summary>
        /// 加载目录树
        /// </summary>
        public void LoadTree(bool loadLocal = true, bool loadSvn = true)
        {
            // 初始化
            this.treeView1.Nodes.Clear();
            DirecotryTreeNode = new Dictionary<string, TreeNode>(StringComparer.OrdinalIgnoreCase);
            SvnProjectDictionary = new Dictionary<string, SvnProjectInfo>(StringComparer.OrdinalIgnoreCase);
            SvnRepositoryTreeNodes = new Dictionary<string, TreeNode>(StringComparer.OrdinalIgnoreCase);
            SearchFolders = AppConfig.Options.SearchFolders;
            Root = null!;
            SvnRoot = null!;

            // 添加本地项目根节点
            if (loadLocal)
            {
                var localProjectNode = new TreeNode()
                {
                    Text = TREE_ROOT_NAME,
                    ToolTipText = TREE_ROOT_NAME,
                    ImageIndex = 0,
                    SelectedImageIndex = 0
                };
                this.treeView1.Nodes.Add(localProjectNode);
                Root = localProjectNode;
            }

            // 添加SVN根节点（如果配置了SVN仓库）
            if (loadSvn && AppConfig.Options.SvnConfig.SvnRepositories != null &&
                AppConfig.Options.SvnConfig.SvnRepositories.Count > 0)
            {
                var svnNode = new TreeNode()
                {
                    Text = TREE_SVN_ROOT_NAME,
                    ToolTipText = TREE_SVN_ROOT_NAME,
                    ImageIndex = 0,
                    SelectedImageIndex = 0
                };
                this.treeView1.Nodes.Add(svnNode);
                // 如果未加载本地节点，svnNode就是 index 0；否则是 index 1
                SvnRoot = svnNode;
            }

            this.treeView1.ExpandAll();
        }

        /// <summary>
        /// 加载SVN项目树
        /// </summary>
        /// <param name="svnProject"></param>
        private async void LoadSvnProjectTree(SvnProjectInfo svnProject)
        {
            this.treeView2.Nodes.Clear();
            this.treeView2.Nodes.Add(svnProject.ProjectName);
            var root = this.treeView2.Nodes[0];
            root.ToolTipText = svnProject.SvnUrl;

            try
            {
                var items = await SvnHelper.ListSvnPathAsync(svnProject.SvnUrl);
                foreach (var item in items)
                {
                    var node = new TreeNode()
                    {
                        Text = item.Name,
                        ToolTipText = item.Url,
                        ImageIndex = item.ItemType == SvnItemType.Directory ? 0 : 2,
                        SelectedImageIndex = item.ItemType == SvnItemType.Directory ? 0 : 2,
                    };
                    root.Nodes.Add(node);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载SVN项目内容失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            this.treeView2.ExpandAll();
        }

        /// <summary>
        /// 加载项目树
        /// </summary>
        /// <param name="projectPath"></param>
        private void LoadProjectTree(string projectPath)
        {
            this.treeView2.Nodes.Clear();

            // 使用项目路径的目录名作为根节点名称
            var projectName = new DirectoryInfo(projectPath).Name;
            this.treeView2.Nodes.Add(projectName);
            var root = this.treeView2.Nodes[0];

            var files = Directory.GetFiles(projectPath);
            var directories = Directory.GetDirectories(projectPath);
            var matchItems = MatchVS(projectPath);

            for (int i = 0; i < files.Length; i++)
            {
                var node = new TreeNode()
                {
                    Text = new FileInfo(files[i]).Name,
                    ToolTipText = files[i],
                };
                root.Nodes.Add(node);
                foreach (var item in matchItems)
                {
                    if (item == files[i])
                    {
                        root.Nodes[i].ForeColor = Color.FromArgb(128, 0, 128);
                        root.Nodes[i].SelectedImageIndex = 1;
                        root.Nodes[i].ImageIndex = 1;
                    }
                    else
                    {
                        root.Nodes[i].SelectedImageIndex = 2;
                        root.Nodes[i].ImageIndex = 2;
                    }
                }
            }

            var count = files.Length;
            foreach (var dir in directories)
            {
                var node = new TreeNode()
                {
                    Text = new DirectoryInfo(dir).Name,
                    ToolTipText = dir
                };
                root.Nodes.Add(node);
                foreach (var item in matchItems)
                {
                    var arr = item.Split('\\').ToList();
                    arr.Remove(arr.Last());
                    if (string.Join('\\', arr) == dir)
                    {
                        var childNode = new TreeNode()
                        {
                            Text = new FileInfo(item).Name,
                            ToolTipText = new FileInfo(item).FullName,
                            ForeColor = Color.FromArgb(128, 0, 128),
                            SelectedImageIndex = 1,
                            ImageIndex = 1,
                        };
                        root.Nodes[count].Nodes.Add(childNode);
                    }
                }
                count++;
            }
            this.treeView2.ExpandAll();
        }

        private void treeView1_NodeMouseClick(object? sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node == null)
            {
                return;
            }

            var selectedNode = e.Node;
            var nodeName = selectedNode.ToolTipText ?? string.Empty;

            // 重置选择状态
            SelectedPath = string.Empty;
            SelectedVsPath = string.Empty;
            SelectedSvnProject = null;
            SelectedRepositoryUrl = string.Empty;

            // 检查是否点击了根级节点（本地项目或SVN项目）
            if (nodeName == TREE_ROOT_NAME || nodeName == TREE_SVN_ROOT_NAME || string.IsNullOrEmpty(nodeName))
            {
                this.label2.Text = "项目：";
                this.treeView2.Nodes.Clear();
                UpdateButtonsState();
                return;
            }

            // 仓库分组节点（仓库URL在 ToolTipText 中, 但不在项目字典里, 也不是本地目录）
            if (SvnRoot != null && SvnRepositoryTreeNodes.ContainsKey(nodeName))
            {
                SelectedRepositoryUrl = nodeName; // 记录仓库URL用于拷贝
                this.label2.Text = "仓库：" + selectedNode.Text;
                this.treeView2.Nodes.Clear();
                // 只允许拷贝，不允许打开文件夹 / 打开VS / 检出
                UpdateButtonsState();
                // 直接启用拷贝按钮
                this.button2.Enabled = true;
                return;
            }

            // 检查是否是SVN项目
            if (SvnProjectDictionary.TryGetValue(nodeName, out var svnProject))
            {
                SelectedSvnProject = svnProject;
                this.label2.Text = "SVN项目：" + svnProject.ProjectName;
                LoadSvnProjectTree(svnProject); // 加载SVN项目内容
                UpdateButtonsState();
                return;
            }

            if (!Directory.Exists(nodeName))
            {
                this.label2.Text = "项目：";
                this.treeView2.Nodes.Clear();
                UpdateButtonsState();
                return;
            }

            var folderInfo = FolderHelper.GetFolderInfo(nodeName);
            SelectedPath = folderInfo.FolderPath;

            // 选择的是项目目录
            if (!SearchFolders.Contains(SelectedPath))
            {
                this.label2.Text = "项目：" + SelectedPath.Split('\\').Last();
                LoadProjectTree(SelectedPath);
            }
            else
            {
                this.label2.Text = "项目：";
                this.treeView2.Nodes.Clear();
            }
            UpdateButtonsState();
        }

        private void treeView2_NodeMouseClick(object? sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node == null)
            {
                return;
            }

            var selectedNode = e.Node;
            var nodeName = selectedNode.ToolTipText ?? string.Empty;
            SelectedVsPath = string.Empty;

            // 检查是否点击了项目根节点（根节点的ToolTipText为空）
            if (string.IsNullOrEmpty(nodeName))
            {
                this.button2.Enabled = false;
                return;
            }

            this.button2.Enabled = true; // 只要点击了节点就启用

            if (nodeName.EndsWith("sln", StringComparison.OrdinalIgnoreCase))
            {
                SelectedVsPath = nodeName;
                UpdateButtonsState(false);
            }
            else if (File.Exists(nodeName))
            {
                UpdateButtonsState(false);
            }
            else
            {
                SelectedPath = nodeName;
                UpdateButtonsState();
            }
        }

        private void treeView1_NodeMouseDoubleClick(object? sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node == null)
            {
                return;
            }

            var target = e.Node.ToolTipText ?? string.Empty;
            if (string.IsNullOrEmpty(target))
            {
                return;
            }

            if (Directory.Exists(target))
            {
                System.Diagnostics.Process.Start("explorer.exe", target);
                return;
            }

            if (Uri.IsWellFormedUriString(target, UriKind.Absolute))
            {
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
                {
                    FileName = target,
                    UseShellExecute = true
                });
            }
        }

        private void treeView2_NodeMouseDoubleClick(object? sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node == null)
            {
                return;
            }

            var target = e.Node.ToolTipText ?? string.Empty;
            if (string.IsNullOrEmpty(target))
            {
                return;
            }

            if (Path.GetExtension(target).Equals(".sln", StringComparison.OrdinalIgnoreCase))
            {
                SelectedVsPath = target;
                var exePath = GetDevenvPath(SelectedVsPath);
                var path = SelectedVsPath;
                System.Diagnostics.Process.Start(exePath, $@"""{path}""");
            }
        }
        #endregion

        #region 菜单栏操作
        private void 检索路径ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var form = new SearchFoldersSetting();
            form.TreeViewRefresh = () => this.LoadTree();
            form.Show();
        }

        private void 默认解决方案路径ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var form = new SlnPathSetting();
            form.StartPosition = FormStartPosition.CenterScreen;
            form.Show();
        }

        private void SVN设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var form = new SvnSetting();
            form.ShowDialog();
            // 重新加载树形结构以反映SVN设置的更改
            LoadTree();
        }

        private void 新增检索目录ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            // 打开目录选择器
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "请选择项目目录";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var folderPath = dialog.SelectedPath;
                if (SearchFolders.Contains(folderPath))
                {
                    MessageBox.Show("请勿重复添加", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                SearchFolders.Add(folderPath);
                // 更新 appsettings
                AppConfig.UpdateSection("SearchFolders", SearchFolders);
                LoadTree();
            }
        }
        #endregion

        #region 操作
        /// <summary>
        /// 打开文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExplorer_Click(object sender, EventArgs e)
        {
            if (SelectedSvnProject != null)
            {
                MessageBox.Show("SVN项目需要先检出到本地", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (string.IsNullOrEmpty(SelectedPath))
            {
                MessageBox.Show("请选择文件夹", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            System.Diagnostics.Process.Start("explorer.exe", SelectedPath);
        }

        /// <summary>
        /// 检索
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnSearch_Click(object sender, EventArgs e)
        {
            var searchKeyword = this.textBox1.Text.Trim();
            if (string.IsNullOrEmpty(searchKeyword))
            {
                MessageBox.Show("请输入搜索关键字", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 禁用搜索按钮防止重复点击
            btnSearch.Enabled = false;
            btnSearch.Text = "搜索中...";

            try
            {
                // 仅加载本地根节点
                LoadTree(loadLocal: true, loadSvn: false);

                // 只进行本地项目搜索
                var localCount = await SearchLocalProjects(searchKeyword);

                this.treeView1.ExpandAll();
                this.SelectedPath = "";
                this.SelectedVsPath = "";
                this.SelectedSvnProject = null;

                // 更新搜索结果标签
                this.searchResultLabel.Text = $"本地搜索结果：查询到 {localCount} 个项目";

                if (localCount == 0)
                {
                    MessageBox.Show("未找到匹配的本地项目", "搜索结果", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"本地搜索时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                btnSearch.Enabled = true;
                btnSearch.Text = "本地查询";
            }
        }

        /// <summary>
        /// 搜索本地项目
        /// </summary>
        /// <param name="searchKeyword">搜索关键字</param>
        /// <returns>找到的项目数量</returns>
        private async Task<int> SearchLocalProjects(string searchKeyword)
        {
            if (SearchFolders == null || SearchFolders.Count == 0)
            {
                return 0;
            }

            var totalCount = 0;
            var groupedMatches = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);

            await Task.Run(() =>
            {
                foreach (var dir in SearchFolders)
                {
                    if (string.IsNullOrWhiteSpace(dir))
                    {
                        continue;
                    }

                    try
                    {
                        if (!Directory.Exists(dir))
                        {
                            continue;
                        }

                        var subDirectories = Directory.GetDirectories(dir);
                        foreach (var folder in subDirectories)
                        {
                            var directoryInfo = new DirectoryInfo(folder);
                            if (!directoryInfo.Exists)
                            {
                                continue;
                            }

                            if (directoryInfo.Name.IndexOf(searchKeyword, StringComparison.OrdinalIgnoreCase) >= 0)
                            {
                                if (!groupedMatches.TryGetValue(dir, out var folders))
                                {
                                    folders = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                                    groupedMatches.Add(dir, folders);
                                }

                                if (folders.Add(directoryInfo.FullName))
                                {
                                    totalCount++;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // 记录错误但不中断搜索
                        Console.WriteLine($"搜索目录失败: {dir}, 错误: {ex.Message}");
                    }
                }
            });

            if (groupedMatches.Count == 0)
            {
                return totalCount;
            }

            if (this.IsHandleCreated)
            {
                this.Invoke(new Action(() =>
                {
                    foreach (var kvp in groupedMatches)
                    {
                        var groupNode = EnsureLocalGroupNode(kvp.Key);
                        foreach (var folderPath in kvp.Value.OrderBy(path => path, StringComparer.OrdinalIgnoreCase))
                        {
                            if (!Directory.Exists(folderPath))
                            {
                                continue;
                            }

                            var info = new DirectoryInfo(folderPath);
                            var projectNode = new TreeNode()
                            {
                                Name = folderPath,
                                Text = info.Name,
                                ToolTipText = folderPath,
                                ForeColor = Color.FromArgb(0, 0, 139),
                                ImageIndex = 0,
                                SelectedImageIndex = 0
                            };

                            groupNode.Nodes.Add(projectNode);
                        }

                        groupNode.Expand();
                    }
                }));
            }

            return totalCount;
        }

        /// <summary>
        /// 搜索SVN项目
        /// </summary>
        /// <param name="searchKeyword">搜索关键字</param>
        /// <returns>找到的项目数量</returns>
        private async Task<int> SearchSvnProjects(string searchKeyword)
        {
            var svnProjects = await SvnHelper.SearchProjectsFromSvnAsync(searchKeyword);

            if (SvnRoot == null || svnProjects.Count == 0)
            {
                return svnProjects.Count;
            }

            var groupedProjects = svnProjects
                .GroupBy(project => project.Repository, StringComparer.OrdinalIgnoreCase);

            foreach (var group in groupedProjects)
            {
                var firstProject = group.First();
                var repositoryNode = EnsureSvnRepositoryNode(group.Key, firstProject.RepositoryName);

                foreach (var project in group.OrderBy(p => p.ProjectName, StringComparer.OrdinalIgnoreCase))
                {
                    if (repositoryNode.Nodes.ContainsKey(project.SvnUrl))
                    {
                        continue;
                    }

                    var node = new TreeNode()
                    {
                        Name = project.SvnUrl,
                        Text = project.ProjectName,
                        ToolTipText = project.SvnUrl,
                        ForeColor = Color.FromArgb(128, 0, 128),
                        ImageIndex = 0,
                        SelectedImageIndex = 0
                    };

                    repositoryNode.Nodes.Add(node);
                    repositoryNode.Expand();

                    if (!SvnProjectDictionary.ContainsKey(project.SvnUrl))
                    {
                        SvnProjectDictionary[project.SvnUrl] = project;
                    }
                }
            }

            return svnProjects.Count;
        }

        private TreeNode EnsureLocalGroupNode(string directoryPath)
        {
            if (Root == null)
            {
                throw new InvalidOperationException("本地根节点尚未初始化");
            }

            if (!DirecotryTreeNode.TryGetValue(directoryPath, out var node) || node == null)
            {
                var displayName = FolderHelper.GetFolderName(directoryPath);
                if (string.IsNullOrEmpty(displayName))
                {
                    displayName = directoryPath;
                }

                node = new TreeNode()
                {
                    Name = directoryPath,
                    Text = displayName,
                    ToolTipText = directoryPath,
                    ImageIndex = 0,
                    SelectedImageIndex = 0
                };

                Root.Nodes.Add(node);
                DirecotryTreeNode[directoryPath] = node;
            }

            return node;
        }

        private TreeNode EnsureSvnRepositoryNode(string repositoryUrl, string repositoryDisplayName)
        {
            if (SvnRoot == null)
            {
                throw new InvalidOperationException("SVN根节点尚未初始化");
            }

            if (!SvnRepositoryTreeNodes.TryGetValue(repositoryUrl, out var node) || node == null)
            {
                var displayName = string.IsNullOrEmpty(repositoryDisplayName)
                    ? GetRepositoryDisplayName(repositoryUrl)
                    : repositoryDisplayName;

                node = new TreeNode()
                {
                    Name = repositoryUrl,
                    Text = displayName,
                    ToolTipText = repositoryUrl,
                    ImageIndex = 0,
                    SelectedImageIndex = 0
                };

                SvnRoot.Nodes.Add(node);
                SvnRepositoryTreeNodes[repositoryUrl] = node;
            }

            return node;
        }

        private static string GetRepositoryDisplayName(string repositoryUrl)
        {
            if (string.IsNullOrWhiteSpace(repositoryUrl))
            {
                return "SVN 仓库";
            }

            var trimmed = repositoryUrl.TrimEnd('/', '\\');
            var index = trimmed.LastIndexOfAny(new[] { '/', '\\' });
            if (index >= 0 && index < trimmed.Length - 1)
            {
                return trimmed.Substring(index + 1);
            }

            return trimmed;
        }

        /// <summary>
        /// 检出SVN项目
        /// </summary>
        private async void btnCheckoutSvn_Click(object? sender, EventArgs e)
        {
            if (SelectedSvnProject == null)
            {
                MessageBox.Show("请先选择一个SVN项目", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            var cachePath = AppConfig.Options.SvnConfig.LocalCachePath;
            if (string.IsNullOrEmpty(cachePath))
            {
                MessageBox.Show("请先在SVN设置中配置本地缓存路径", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (!Directory.Exists(cachePath))
            {
                try
                {
                    Directory.CreateDirectory(cachePath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"创建缓存目录失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            var localPath = Path.Combine(cachePath, SelectedSvnProject.ProjectName);

            // 如果本地已存在该项目，询问是否覆盖
            if (Directory.Exists(localPath))
            {
                var result = MessageBox.Show("本地已存在该项目，是否覆盖？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.No)
                    return;

                try
                {
                    Directory.Delete(localPath, true);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"删除现有目录失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            // 显示进度
            var progressForm = new Form()
            {
                Text = "正在检出...",
                Size = new Size(300, 100),
                FormBorderStyle = FormBorderStyle.FixedDialog,
                MaximizeBox = false,
                MinimizeBox = false,
                StartPosition = FormStartPosition.CenterScreen
            };

            var label = new Label()
            {
                Text = "正在从SVN检出项目，请稍候...",
                AutoSize = true,
                Location = new Point(20, 30)
            };
            progressForm.Controls.Add(label);
            progressForm.Show();

            try
            {
                var success = await SvnHelper.CheckoutProjectAsync(SelectedSvnProject.SvnUrl, localPath);
                progressForm.Close();

                if (success)
                {
                    MessageBox.Show("项目检出成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    // 检出成功后，将路径设为选中状态并加载项目树
                    SelectedPath = localPath;
                    SelectedSvnProject = null;
                    this.label2.Text = "项目：" + Path.GetFileName(localPath);
                    LoadProjectTree(localPath);
                    UpdateButtonsState();
                }
                else
                {
                    MessageBox.Show("项目检出失败，请检查SVN设置和网络连接", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                progressForm.Close();
                MessageBox.Show($"检出项目时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 打开解决方案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpenVS_Click(object sender, EventArgs e)
        {
            var exePath = GetDevenvPath(SelectedVsPath);
            var path = SelectedVsPath;
            System.Diagnostics.Process.Start(exePath, $@"""{path}""");
        }
        #endregion

        private static List<string> GetMatchProject(List<string> pathList)
        {
            var filter = pathList.Where(item => File.Exists(item));
            if (filter.Count() == 1)
            {
                return new List<string>() { filter.First() };
            }
            else if (filter.Count() == 0)
            {
                return new List<string>();
            }
            return filter.ToList();
        }

        private void UpdateButtonsState(bool isFolder = true)
        {
            this.btnExplorer.Enabled = (!string.IsNullOrEmpty(SelectedPath) && isFolder) || SelectedSvnProject != null; // 仓库分组不允许
            this.btnOpenVS.Enabled = !string.IsNullOrEmpty(SelectedVsPath) && !isFolder;
            this.button2.Enabled = !string.IsNullOrEmpty(SelectedPath) ||
                                   !string.IsNullOrEmpty(SelectedVsPath) ||
                                   SelectedSvnProject != null ||
                                   !string.IsNullOrEmpty(SelectedRepositoryUrl);

            // 检出按钮只在选择SVN项目时显示
            if (this.Controls["btnCheckoutSvn"] is Control checkoutControl)
            {
                checkoutControl.Visible = SelectedSvnProject != null;
            }
            else if (SelectedSvnProject != null)
            {
                // 动态创建检出按钮
                var btnCheckout = new Button()
                {
                    Name = "btnCheckoutSvn",
                    Text = "检出项目",
                    Size = new Size(80, 23),
                    Location = new Point(this.btnOpenVS.Location.X + 90, this.btnOpenVS.Location.Y)
                };
                btnCheckout.Click += btnCheckoutSvn_Click;
                this.Controls.Add(btnCheckout);
            }
        }

        private List<string> MatchVS(string projectPath)
        {
            string path = string.Empty;
            var result = new List<string>();

            if (string.IsNullOrEmpty(projectPath) || SearchFolders.Contains(projectPath))
            {
                return result;
            }

            var existItem = AppConfig.Options.SelectedPath.Find(item => item.ProjectPath == projectPath);
            if (existItem != null)
            {
                path = existItem.SlnPath;
                if (File.Exists(path))
                {
                    result.Add(path);
                }
            }
            else
            {
                return GetMatchProject(FolderHelper.GetProjectPathList(projectPath));
            }
            return result;
        }

        private string GetDevenvPath(string projectPath)
        {
            var config = AppConfig.Options.DevenvPath;
            var fallbackPath = config.Default ?? string.Empty;
            var exePath = fallbackPath;
            using (var stream = File.OpenRead(projectPath))
            {
                using (var reader = new StreamReader(stream))
                {
                    var content = reader.ReadToEnd();
                    if (content.Contains("Format Version 10.00"))
                    {
                        exePath = config.ProjectVersion10 ?? fallbackPath;
                    }
                    else if (content.Contains("Format Version 11.00"))
                    {
                        exePath = config.ProjectVersion11 ?? fallbackPath;
                    }
                    else if (content.Contains("Format Version 12.00"))
                    {
                        exePath = config.ProjectVersion12 ?? fallbackPath;
                    }
                    else
                    {
                        exePath = fallbackPath;
                    }
                }
            }
            return exePath;
        }

        /// <summary>
        /// SVN查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button1_Click(object sender, EventArgs e)
        {
            var searchKeyword = this.textBox1.Text.Trim();
            if (string.IsNullOrEmpty(searchKeyword))
            {
                MessageBox.Show("请输入搜索关键字", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 检查是否配置了SVN仓库
            if (AppConfig.Options.SvnConfig.SvnRepositories == null ||
                AppConfig.Options.SvnConfig.SvnRepositories.Count == 0)
            {
                MessageBox.Show("请先在SVN设置中配置SVN仓库地址", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 禁用按钮防止重复点击
            button1.Enabled = false;
            button1.Text = "搜索中...";
            try
            {
                // 仅加载SVN根节点
                LoadTree(loadLocal: false, loadSvn: true);

                // 执行SVN搜索
                var svnCount = await SearchSvnProjects(searchKeyword);

                this.treeView1.ExpandAll();

                // 重置选择状态
                this.SelectedPath = "";
                this.SelectedVsPath = "";
                this.SelectedSvnProject = null;

                // 更新搜索结果标签
                if (svnCount > 0)
                {
                    this.searchResultLabel.Text = $"SVN搜索结果：找到 {svnCount} 个项目";
                }
                else
                {
                    this.searchResultLabel.Text = "SVN搜索结果：未找到匹配项目";
                    MessageBox.Show("未找到匹配的SVN项目", "搜索结果", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"SVN搜索时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.searchResultLabel.Text = "SVN搜索结果：搜索失败";
            }
            finally
            {
                button1.Enabled = true;
                button1.Text = "SVN查询";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string? pathToCopy = null;

            // 优先检查treeView2的选定节点，因为它更具体
            var selectedNode2 = treeView2.SelectedNode;
            if (selectedNode2 != null && !string.IsNullOrEmpty(selectedNode2.ToolTipText))
            {
                pathToCopy = selectedNode2.ToolTipText;
            }
            else if (!string.IsNullOrEmpty(SelectedVsPath))
            {
                pathToCopy = SelectedVsPath;
            }
            else if (!string.IsNullOrEmpty(SelectedPath))
            {
                pathToCopy = SelectedPath;
            }
            else if (SelectedSvnProject != null)
            {
                pathToCopy = SelectedSvnProject.SvnUrl;
            }
            else if (!string.IsNullOrEmpty(SelectedRepositoryUrl))
            {
                pathToCopy = SelectedRepositoryUrl; // 仓库URL
            }

            if (!string.IsNullOrEmpty(pathToCopy))
            {
                Clipboard.SetText(pathToCopy);
                MessageBox.Show("路径已拷贝到剪贴板！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("没有可拷贝的路径。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
    }
}
